package de.jplag.kotlin;

import static de.jplag.kotlin.KotlinTokenType.ASSIGNMENT;
import static de.jplag.kotlin.KotlinTokenType.BREAK;
import static de.jplag.kotlin.KotlinTokenType.CATCH;
import static de.jplag.kotlin.KotlinTokenType.CATCH_BODY_END;
import static de.jplag.kotlin.KotlinTokenType.CATCH_BODY_START;
import static de.jplag.kotlin.KotlinTokenType.CLASS_BODY_BEGIN;
import static de.jplag.kotlin.KotlinTokenType.CLASS_BODY_END;
import static de.jplag.kotlin.KotlinTokenType.CLASS_DECLARATION;
import static de.jplag.kotlin.KotlinTokenType.COMPANION_DECLARATION;
import static de.jplag.kotlin.KotlinTokenType.CONSTRUCTOR;
import static de.jplag.kotlin.KotlinTokenType.CONTINUE;
import static de.jplag.kotlin.KotlinTokenType.CONTROL_STRUCTURE_BODY_END;
import static de.jplag.kotlin.KotlinTokenType.CONTROL_STRUCTURE_BODY_START;
import static de.jplag.kotlin.KotlinTokenType.CREATE_OBJECT;
import static de.jplag.kotlin.KotlinTokenType.DO_WHILE_EXPRESSION_END;
import static de.jplag.kotlin.KotlinTokenType.DO_WHILE_EXPRESSION_START;
import static de.jplag.kotlin.KotlinTokenType.ENUM_CLASS_BODY_BEGIN;
import static de.jplag.kotlin.KotlinTokenType.ENUM_CLASS_BODY_END;
import static de.jplag.kotlin.KotlinTokenType.ENUM_ENTRY;
import static de.jplag.kotlin.KotlinTokenType.FINALLY;
import static de.jplag.kotlin.KotlinTokenType.FINALLY_BODY_END;
import static de.jplag.kotlin.KotlinTokenType.FINALLY_BODY_START;
import static de.jplag.kotlin.KotlinTokenType.FOR_EXPRESSION_BEGIN;
import static de.jplag.kotlin.KotlinTokenType.FOR_EXPRESSION_END;
import static de.jplag.kotlin.KotlinTokenType.FUNCTION;
import static de.jplag.kotlin.KotlinTokenType.FUNCTION_BODY_BEGIN;
import static de.jplag.kotlin.KotlinTokenType.FUNCTION_BODY_END;
import static de.jplag.kotlin.KotlinTokenType.FUNCTION_INVOCATION;
import static de.jplag.kotlin.KotlinTokenType.FUNCTION_LITERAL_BEGIN;
import static de.jplag.kotlin.KotlinTokenType.FUNCTION_LITERAL_END;
import static de.jplag.kotlin.KotlinTokenType.FUNCTION_PARAMETER;
import static de.jplag.kotlin.KotlinTokenType.GETTER;
import static de.jplag.kotlin.KotlinTokenType.IF_EXPRESSION_BEGIN;
import static de.jplag.kotlin.KotlinTokenType.IF_EXPRESSION_END;
import static de.jplag.kotlin.KotlinTokenType.IMPORT;
import static de.jplag.kotlin.KotlinTokenType.INITIALIZER;
import static de.jplag.kotlin.KotlinTokenType.INITIALIZER_BODY_END;
import static de.jplag.kotlin.KotlinTokenType.INITIALIZER_BODY_START;
import static de.jplag.kotlin.KotlinTokenType.OBJECT_DECLARATION;
import static de.jplag.kotlin.KotlinTokenType.PACKAGE;
import static de.jplag.kotlin.KotlinTokenType.PROPERTY_DECLARATION;
import static de.jplag.kotlin.KotlinTokenType.RETURN;
import static de.jplag.kotlin.KotlinTokenType.SETTER;
import static de.jplag.kotlin.KotlinTokenType.THROW;
import static de.jplag.kotlin.KotlinTokenType.TRY_BODY_END;
import static de.jplag.kotlin.KotlinTokenType.TRY_BODY_START;
import static de.jplag.kotlin.KotlinTokenType.TRY_EXPRESSION;
import static de.jplag.kotlin.KotlinTokenType.TYPE_PARAMETER;
import static de.jplag.kotlin.KotlinTokenType.VARIABLE_DECLARATION;
import static de.jplag.kotlin.KotlinTokenType.WHEN_CONDITION;
import static de.jplag.kotlin.KotlinTokenType.WHEN_EXPRESSION_END;
import static de.jplag.kotlin.KotlinTokenType.WHEN_EXPRESSION_START;
import static de.jplag.kotlin.KotlinTokenType.WHILE_EXPRESSION_END;
import static de.jplag.kotlin.KotlinTokenType.WHILE_EXPRESSION_START;

import de.jplag.antlr.AbstractAntlrListener;
import de.jplag.kotlin.grammar.KotlinParser;
import de.jplag.kotlin.grammar.KotlinParser.AnonymousInitializerContext;
import de.jplag.kotlin.grammar.KotlinParser.AssignmentOperatorContext;
import de.jplag.kotlin.grammar.KotlinParser.CallSuffixContext;
import de.jplag.kotlin.grammar.KotlinParser.CatchBodyContext;
import de.jplag.kotlin.grammar.KotlinParser.CatchStatementContext;
import de.jplag.kotlin.grammar.KotlinParser.ClassBodyContext;
import de.jplag.kotlin.grammar.KotlinParser.ClassDeclarationContext;
import de.jplag.kotlin.grammar.KotlinParser.ClassParameterContext;
import de.jplag.kotlin.grammar.KotlinParser.CompanionObjectContext;
import de.jplag.kotlin.grammar.KotlinParser.ConstructorInvocationContext;
import de.jplag.kotlin.grammar.KotlinParser.ControlStructureBodyContext;
import de.jplag.kotlin.grammar.KotlinParser.DoWhileExpressionContext;
import de.jplag.kotlin.grammar.KotlinParser.EnumClassBodyContext;
import de.jplag.kotlin.grammar.KotlinParser.EnumEntryContext;
import de.jplag.kotlin.grammar.KotlinParser.FinallyBodyContext;
import de.jplag.kotlin.grammar.KotlinParser.FinallyStatementContext;
import de.jplag.kotlin.grammar.KotlinParser.ForExpressionContext;
import de.jplag.kotlin.grammar.KotlinParser.FunctionBodyContext;
import de.jplag.kotlin.grammar.KotlinParser.FunctionDeclarationContext;
import de.jplag.kotlin.grammar.KotlinParser.FunctionLiteralContext;
import de.jplag.kotlin.grammar.KotlinParser.FunctionValueParameterContext;
import de.jplag.kotlin.grammar.KotlinParser.GetterContext;
import de.jplag.kotlin.grammar.KotlinParser.IfExpressionContext;
import de.jplag.kotlin.grammar.KotlinParser.ImportHeaderContext;
import de.jplag.kotlin.grammar.KotlinParser.InitBlockContext;
import de.jplag.kotlin.grammar.KotlinParser.ObjectDeclarationContext;
import de.jplag.kotlin.grammar.KotlinParser.PackageHeaderContext;
import de.jplag.kotlin.grammar.KotlinParser.PrimaryConstructorContext;
import de.jplag.kotlin.grammar.KotlinParser.PropertyDeclarationContext;
import de.jplag.kotlin.grammar.KotlinParser.SecondaryConstructorContext;
import de.jplag.kotlin.grammar.KotlinParser.SetterContext;
import de.jplag.kotlin.grammar.KotlinParser.TryBodyContext;
import de.jplag.kotlin.grammar.KotlinParser.TryExpressionContext;
import de.jplag.kotlin.grammar.KotlinParser.TypeParameterContext;
import de.jplag.kotlin.grammar.KotlinParser.VariableDeclarationContext;
import de.jplag.kotlin.grammar.KotlinParser.WhenConditionContext;
import de.jplag.kotlin.grammar.KotlinParser.WhenExpressionContext;
import de.jplag.kotlin.grammar.KotlinParser.WhileExpressionContext;

class KotlinListener extends AbstractAntlrListener {

    KotlinListener() {
        visit(PackageHeaderContext.class).map(PACKAGE);
        visit(ImportHeaderContext.class).map(IMPORT);
        visit(ClassDeclarationContext.class).map(CLASS_DECLARATION);
        visit(ObjectDeclarationContext.class).map(OBJECT_DECLARATION);
        visit(CompanionObjectContext.class).map(COMPANION_DECLARATION);
        visit(TypeParameterContext.class).map(TYPE_PARAMETER);
        visit(PrimaryConstructorContext.class).map(CONSTRUCTOR);
        visit(ClassParameterContext.class).map(PROPERTY_DECLARATION);
        visit(ClassBodyContext.class).map(CLASS_BODY_BEGIN, CLASS_BODY_END);
        visit(EnumClassBodyContext.class).map(ENUM_CLASS_BODY_BEGIN, ENUM_CLASS_BODY_END);
        visit(EnumEntryContext.class).map(ENUM_ENTRY);
        visit(SecondaryConstructorContext.class).map(CONSTRUCTOR);
        visit(PropertyDeclarationContext.class).map(PROPERTY_DECLARATION);
        visit(AnonymousInitializerContext.class).map(INITIALIZER);
        visit(InitBlockContext.class).map(INITIALIZER_BODY_START, INITIALIZER_BODY_END);
        visit(FunctionDeclarationContext.class).map(FUNCTION);
        visit(GetterContext.class).map(GETTER);
        visit(SetterContext.class).map(SETTER);
        visit(FunctionValueParameterContext.class).map(FUNCTION_PARAMETER);
        visit(FunctionBodyContext.class).map(FUNCTION_BODY_BEGIN, FUNCTION_BODY_END);
        visit(FunctionLiteralContext.class).map(FUNCTION_LITERAL_BEGIN, FUNCTION_LITERAL_END);
        visit(ForExpressionContext.class).map(FOR_EXPRESSION_BEGIN, FOR_EXPRESSION_END);
        visit(IfExpressionContext.class).map(IF_EXPRESSION_BEGIN, IF_EXPRESSION_END);
        visit(WhileExpressionContext.class).map(WHILE_EXPRESSION_START, WHILE_EXPRESSION_END);
        visit(DoWhileExpressionContext.class).map(DO_WHILE_EXPRESSION_START, DO_WHILE_EXPRESSION_END);
        visit(TryExpressionContext.class).map(TRY_EXPRESSION);
        visit(TryBodyContext.class).map(TRY_BODY_START, TRY_BODY_END);
        visit(CatchStatementContext.class).map(CATCH);
        visit(CatchBodyContext.class).map(CATCH_BODY_START, CATCH_BODY_END);
        visit(FinallyStatementContext.class).map(FINALLY);
        visit(FinallyBodyContext.class).map(FINALLY_BODY_START, FINALLY_BODY_END);
        visit(WhenExpressionContext.class).map(WHEN_EXPRESSION_START, WHEN_EXPRESSION_END);
        visit(WhenConditionContext.class).map(WHEN_CONDITION);
        visit(ControlStructureBodyContext.class).map(CONTROL_STRUCTURE_BODY_START, CONTROL_STRUCTURE_BODY_END);
        visit(VariableDeclarationContext.class).map(VARIABLE_DECLARATION);
        visit(ConstructorInvocationContext.class).map(CREATE_OBJECT);
        visit(CallSuffixContext.class).map(FUNCTION_INVOCATION);
        visit(AssignmentOperatorContext.class).map(ASSIGNMENT);

        visit(KotlinParser.THROW).map(THROW);
        visit(KotlinParser.RETURN).map(RETURN);
        visit(KotlinParser.CONTINUE).map(CONTINUE);
        visit(KotlinParser.BREAK).map(BREAK);
        visit(KotlinParser.BREAK_AT).map(BREAK);
    }
}
